<?php

/**
 * 配件管理
 */

namespace app\admin\service;

use app\admin\model\Product as ProductModel;
use app\admin\model\ProductRelation;
use think\facade\Db;
use think\Service;
use app\common\SkuGenerator;
use think\Exception;
use app\admin\model\Images as ImagesModel;

class Attachment extends BaseService
{

    /**
     * 获取配件列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($param = [], $page = 1, $limit = 10)
    {
        $where = [['is_del', '=', 0], ['type', '=', 2]];
        $arrData = ['code' => 0, 'message' => 'success'];
        if ($param['cname']) {
            $where[] = ['cname', 'like', '%' . $param['cname'] . '%'];
        }
        if ($param['sku']) {
            $where[] = ['sku', 'like', '%' . $param['sku'] . '%'];
        }

        if ($param['code']) {
            $where[] = ['code', 'like', '%' . $param['code'] . '%'];
        }

        if ($param['abbr']) {
            $where[] =  ['abbr', 'like', '%' . $param['abbr'] . '%'];
        }


        if ($param['brand']) {
            $where['brand'] = [$param['brand']];
        }

        $oProductModel = ProductModel::where($where);

        if ($param['category'] && $param['category'] != 0) {
            $oProductModel = $oProductModel->where('category', 'in', Db::name('product_category')->where('is_del', 0)->where('parent_id', $param['category'])->whereOr('id', $param['category'])->column('id'));
        }

        // 处理 is_merge_product 参数
        if (isset($param['is_merge_product'])) {
            $relationModel = new ProductRelation();
            $pids = $relationModel->where('is_del', 0)->column('pid');

            if ($param['is_merge_product'] == 1) {
                $oProductModel = $oProductModel->whereIn('id', $pids);
            } elseif ($param['is_merge_product'] == 0) {
                $oProductModel = $oProductModel->whereNotIn('id', $pids);
            }
        }

        // 处理 is_have_inventory 参数
        if (isset($param['is_have_inventory'])) {
            // 获取有库存的商品ID
            $productIds = Db::name('inventory')
                ->where('is_del', 0)
                ->where(function ($query) {
                    $query->whereRaw('(available_qty - lock_qty) > 0')
                        ->whereOr('allow_zero_stock_sale', 1);
                })
                ->group('productid')
                ->column('productid');

            if ($param['is_have_inventory'] == 1) {
                $oProductModel = $oProductModel->whereIn('id', $productIds);
            } elseif ($param['is_have_inventory'] == 0) {
                $oProductModel = $oProductModel->whereNotIn('id', $productIds);
            }
        }

        $total = $oProductModel->count();
        $result = $oProductModel
            ->with(['get_category_value'])
            ->field('id, cname, abbr, code,brand, color_specs, power,working_voltage,noise_level,network_conn_method,operation_temperature,weight,gross_weight, billing_weight,status,sales_rate,remark,free_shipping,apply_rules,contain_battery,has_magnetic,sku,category')
            ->page($page, $limit)
            ->order('id desc')
            ->select()
            ->toArray();
        foreach ($result as $k => &$v) {
            $v['brand'] = (string)  $v['brand'];
        }

        $arrData['data'] = ['list' => $result, 'total' => $total];
        return $arrData;
    }

    /**
     * 删除单条或多条配件数据
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete($param)
    {
        $where = [['is_del', '=', '0'], ['id', 'in', $param['ids']]];
        $oProductModel = ProductModel::where($where);
        $product = $oProductModel->find();
        if (!$product) {
            return ['code' => 1, 'message' => '获取配件信息失败！'];
        }

        Db::startTrans();

        try {
            $result = $oProductModel->update(['is_del' => time()]);
            $productAccessoriesResult = Db::name('product_accessories')
                ->whereIn('accessories_id', $param['ids'])
                ->update(['status' => 0, 'update_time' => date('Y-m-d H:i:s')]);
            // 提交事务
            Db::commit();
            $this->logger->logOperation($param['ids'], 'attachment', '删除', '删除配件');
            $this->clearCTerminalCache(6); // 清除C端产品缓存
            return ['code' => 0, 'message' => '删除配件成功！'];
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => '删除配件失败！' . $e->getMessage()];
        }
    }

    /**
     * 添加修改配件
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function create($param)
    {
        $model = new ProductModel();
        $exists = $model->where('is_del', 0)->where(function ($query) use ($param) {
            $query->where('cname', $param['cname'])->whereOr('code', $param['code']);
        })->find();
        if ($exists) {
            return ['code' => 200001, 'message' => '配件名称或编码重复'];
        }


        $param['type'] = 2;
        $generator = new SkuGenerator();
        $param['sku'] = $generator->generateSku($param['type']);
        $param['creator'] = $param['operator_id'];
        $param['create_time'] = date('Y-m-d H:i:s');
        $param['photo'] = implode(',', $param['photo']);

        $productIdArr = $param['pid'];



        Db::startTrans();

        try {
            $res = $model->create($param); // 执行插入
            if ($res) {
                // 如果产品成功保存
                $middleTableData = [];

                // 处理新增或更新的商品
                foreach ($productIdArr as $value) {
                    $middleTableData[] = [
                        'product_id' => $value,
                        'accessories_id' => $res->id,
                        'status' => 1,  // 新增的关联状态设为 1
                        'create_time' => date('Y-m-d H:i:s'),
                        'creator' => $param['operator_id'],
                    ];
                }

                // 批量插入新增的关联记录，避免重复插入
                if (!empty($middleTableData)) {
                    Db::name('product_accessories')->insertAll($middleTableData);
                }
                $this->clearCTerminalCache(6); // 清除C端产品缓存
                // 提交事务
                Db::commit();

                // 记录操作日志
                $this->logger->logOperation($res->id, 'attachment',  '添加', '保存配件');

                return ['code' => 0, 'message' => '保存配件成功！'];
            }
        } catch (\Exception $e) {
            Db::rollback();

            throw new \Exception('服务器内部错误：' . $e->getMessage());
        }
    }

    /**
     * 配件修改
     * @param $condation
     * @param $data
     * @return array
     */
    public function update($condation, $data)
    {
        $model = new ProductModel();
        $exists = $model->where('is_del', 0)->where('id', '<>', $condation['id'])->where(function ($query) use ($data) {
            $query->where('cname', $data['cname'])->whereOr('code', $data['code']);
        })->find();

        if ($exists) {
            return ['code' => 200001, 'message' => '配件名称或编码重复'];
        }

        $res = $this->getInfo($condation);
        $res = $res['data'];
        if (isset($res['photo']) && $res['photo']) {
            $res['photo'] = implode(',', $res['photo']);
        }

        if (isset($data['photo']) && $data['photo']) {
            $data['photo'] = implode(',', $data['photo']);
        }

        if (!isset($res['sku']) && !$res['sku']) {
            $generator = new SkuGenerator();
            $data['sku'] = $generator->generateSku($res['type']);
        }

        $update_data = [];
        $legal_fields = array_keys($model->schema);
        foreach ($data as $key => $value) {
            if (in_array($key, $legal_fields)  &&   $res[$key] != $value) {
                $update_data[$key] = $value;
            }
        }
        $data['updater'] = $data['operator_id'];
        $data['update_time'] = date('Y-m-d H:i:s');
        $productIdArr = $data['pid'];
        $model->startTrans();

        try {
            $result = $model->where('is_del', 0)->where($condation)->update($update_data);

            if ($result > -1) {
                // 如果产品成功保存
                $middleTableData = [];
                $existingProductIds = Db::name('product_accessories')
                    ->where('accessories_id', $res['id'])
                    ->column('product_id');  // 获取已经关联的所有 product_id，避免重复插入

                // 计算需要逻辑删除的商品ID（旧的关联商品）
                $deleteProductIds = array_diff($existingProductIds, $productIdArr);
                // 计算需要新增或更新的商品ID（新的关联商品）
                $addProductIds = array_diff($productIdArr, $existingProductIds);

                // 处理逻辑删除：将不再关联的商品的状态改为 0
                if (!empty($deleteProductIds)) {
                    Db::name('product_accessories')
                        ->whereIn('product_id', $deleteProductIds)
                        ->where('accessories_id', $res['id'])
                        ->update(['status' => 0, 'update_time' => date('Y-m-d H:i:s')]);
                }

                // 处理新增或更新的商品
                foreach ($productIdArr as $value) {
                    // 尝试更新该商品的状态为 1
                    $affectedRows = Db::name('product_accessories')
                        ->where('product_id', $value)
                        ->where('accessories_id', $res['id'])
                        ->update(['status' => 1, 'update_time' => date('Y-m-d H:i:s')]);

                    if ($affectedRows === 0) {
                        // 如果没有记录被更新，说明该商品与配件没有关联，或者已经是有效状态（status为1），因此需要新增
                        $middleTableData[] = [
                            'product_id' => $value,
                            'accessories_id' => $res['id'],
                            'status' => 1,  // 新增的关联状态设为 1
                            'create_time' => date('Y-m-d H:i:s'),
                            'creator' => $data['operator_id'],
                        ];
                    }
                }

                // 批量插入新增的关联记录，避免重复插入
                if (!empty($middleTableData)) {
                    Db::name('product_accessories')->insertAll($middleTableData);
                }
                $this->clearCTerminalCache(6); // 清除C端产品缓存
            }

            $this->logger->logOperation($res['id'], 'Product', '修改', '修改商品信息');
            $model->commit();
            return ['code' => 0, 'message' => '操作成功'];
        } catch (\Exception $e) {
            $model->rollback();
            return ['code' => 1, 'message' => '修改配件失败！' . $e->getMessage()];
        }
    }

    /**
     * 获取单个配件信息
     * @param int $id 配件ID
     * @return array
     */
    public function getInfo($param)
    {
        $where = [['is_del', '=', '0'], ['id', '=', $param['id']]];
        $oAttachmentModel =
            ProductModel::with(['get_parent_name', 'get_category_value'])
            ->append(['is_advance_text', 'condition_text'])
            ->where($where)
            ->find()
            ->toArray();

        if (0 === $oAttachmentModel['brand']) {
            $oAttachmentModel['brand'] = null;
        } else {
            $oAttachmentModel['brand'] = (string)$oAttachmentModel['brand'];
        }

        // 处理商品图片信息
        $formatPhoto = [];
        $formatPhoto_ids = [];
        if ($oAttachmentModel['photo']) {
            $oImagesModel = ImagesModel::whereIn('id', explode(',', $oAttachmentModel['photo']))->select();
            foreach ($oImagesModel as $key => $item) {
                $formatPhoto[] = [
                    'id' => $item->id,
                    'url' => $item->url
                ];
                $formatPhoto_ids[] = $item->id;
            }
        }
        $oAttachmentModel['photo'] = $formatPhoto_ids;
        $oAttachmentModel['photo_urls'] = $formatPhoto;

        // 获取关联商品
        $productIds = Db::name('product_accessories')
            ->alias('a')
            ->join('product p', 'a.product_id = p.id')
            ->where([
                'a.accessories_id' => $param['id'],
                'a.status' => 1,
                'p.type' => 1,
            ])
            ->column('product_id as id ,code, p.cname,p.status');
        if (0 !== count($productIds)) {
            $oAttachmentModel['product_accessories_linked_data'] = $productIds;
        } else {
            $oAttachmentModel['product_accessories_linked_data'] = [];
        }


        if (!$oAttachmentModel) {
            return ['code' => 1, 'message' => '获取配件信息失败！'];
        }
        return ['code' => 0, 'message' => 'success', 'data' => $oAttachmentModel];
    }
}
